﻿using System;
using System.Configuration;

using OnlineFamilyCalendar.Common.Security;
using OnlineFamilyCalendar.Model;
using OnlineFamilyCalendar.Data;
using OnlineFamilyCalendar.Common.Configuration;
using OnlineFamilyCalendar.Common.Cryptography;

namespace OnlineFamilyCalendar.Service
{
    public class FamilyMemberService : IFamilyMemberService
    {
        private IFamilyMemberRepository _repository;
        private IOnlineFamilyCalendarEntities _context;
        OnlineFamilyCalendarRegistrationSection _config;

        public FamilyMemberService()
        {
            _context = new OnlineFamilyCalendarEntities();
            _repository = new FamilyMemberRepository(_context);
        }

        public OnlineFamilyCalendarIdentity AuthenticateFamilyMember(string loginName, string password)
        {
            //ToDo (Try / Catch, Log)
            OnlineFamilyCalendarIdentity userIdentity = new OnlineFamilyCalendarIdentity
            {
                Name = loginName,
                IsAuthenticated = false
            };

            FamilyMember familyMember = _repository.GetFamilyMemberByLoginname(loginName);
            if (familyMember == null)
                return userIdentity;

            userIdentity.FamilyMemberId = familyMember.FamilyMemberId;
            userIdentity.Role = familyMember.RoleName;

            familyMember.LoginInformation.Authenticate(password);
            if (familyMember.LoginInformation.IsAuthenticated)
                userIdentity.IsAuthenticated = true;

            return userIdentity;
        }

        public string RegisterNewFamilyMember(string loginName, string password, string emailAddress)
        {
            //ToDo (Try / Catch, Log)

            _config = (OnlineFamilyCalendarRegistrationSection)ConfigurationManager.GetSection("onlineFamilyCalendarRegistration");

            LoginInformation loginInformation = LoginInformation.Create(loginName, password);

            FamilyMember familyMember = FamilyMember.Create(loginInformation);
            familyMember.EmailAddress = emailAddress;

            _repository.AddLoginInformation(loginInformation);
            _repository.AddFamilyMember(familyMember);
            _repository.SaveChanges();

            return GetEncryptedFamilyMemberId(familyMember.FamilyMemberId.ToString());
            //ToDo Send Registration eMail to the user
        }

        public void ActivateFamilyMember(string cypherFamilyMemberIdentifier)
        {
            _config = (OnlineFamilyCalendarRegistrationSection)ConfigurationManager.GetSection("onlineFamilyCalendarRegistration");
            Guid familyMemberId = new Guid(GetDecryptedFamilyMemberId(cypherFamilyMemberIdentifier));
            FamilyMember familyMember = _repository.GetFamilyMemberByFamilyMemberId(familyMemberId);
            LoginInformation loginInformation = familyMember.LoginInformation;
            loginInformation.Activate();
            _repository.UpdateLoginInformation(loginInformation);
            _repository.SaveChanges();
        }

        public void DeleteFamilyMember(Guid familyMemberId)
        {
            throw new NotImplementedException();
        }

        public void ChangePassword(Guid familyMemberId, string newPassword)
        {
            throw new NotImplementedException();
        }

        public void ChangeEmailAddress(Guid familyMemberId, string newEmailAddress)
        {
            throw new NotImplementedException();
        }

        #region Private Methods
        private string GetEncryptedFamilyMemberId(string familyMemberId)
        {
            EncryptionHelper encryptionHelper = new EncryptionHelper(_config.EncryptionKey);
            return encryptionHelper.EncryptData(familyMemberId);
        }

        private string GetDecryptedFamilyMemberId(string encryptedFamilyMemberId)
        {
            EncryptionHelper encryptionHelper = new EncryptionHelper(_config.EncryptionKey);
            return encryptionHelper.DecryptData(encryptedFamilyMemberId);
        }
        #endregion

        // ToDo Dispose
    }
}
